package com.alienlab.finder.service.impl;

import com.alienlab.finder.domain.User;
import com.alienlab.finder.model.WXSessionModel;
import com.alienlab.finder.repository.AuthorityRepository;
import com.alienlab.finder.repository.UserRepository;
import com.alienlab.finder.security.jwt.TokenProvider;
import com.alienlab.finder.service.AppUserService;
import com.alienlab.finder.domain.AppUser;
import com.alienlab.finder.repository.AppUserRepository;
import com.alienlab.finder.service.UserService;
import com.alienlab.finder.service.dto.UserDTO;
import com.alienlab.finder.service.dto.UserInfoDTO;
import com.alienlab.finder.service.dto.globalData;
import com.alienlab.finder.service.util.HttpClientUtil;
import com.alienlab.finder.service.util.JsonUtils;
import com.alienlab.finder.web.rest.errors.InternalServerErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.*;

/**
 * Service Implementation for managing AppUser.
 */
@Service
@Transactional
public class AppUserServiceImpl implements AppUserService {

    private final Logger log = LoggerFactory.getLogger(AppUserServiceImpl.class);

    private final AppUserRepository appUserRepository;
    private final UserService userService;
    private final UserRepository userRepository;
    private final AuthenticationManager authenticationManager;
    private final TokenProvider tokenProvider;
    private final AuthorityRepository authorityRepository;


    public AppUserServiceImpl(AuthorityRepository authorityRepository,TokenProvider tokenProvider,UserRepository userRepository,AppUserRepository appUserRepository, UserService userService,AuthenticationManager authenticationManager) {
        this.userService =  userService;
        this.appUserRepository = appUserRepository;
        this.userRepository = userRepository;
        this.authenticationManager = authenticationManager;
        this.tokenProvider = tokenProvider;
        this.authorityRepository =authorityRepository;

    }

    /**
     * Save a appUser.
     *
     * @param appUser the entity to save
     * @return the persisted entity
     */
    @Override
    public AppUser save(AppUser appUser) {
        log.debug("Request to save AppUser : {}", appUser);
        return appUserRepository.save(appUser);
    }

    /**
     * Get all the appUsers.
     *
     * @param pageable the pagination information
     * @return the list of entities
     */
    @Override
    @Transactional(readOnly = true)
    public Page<AppUser> findAll(Pageable pageable) {
        log.debug("Request to get all AppUsers");
        return appUserRepository.findAll(pageable);
    }


    /**
     * Get one appUser by id.
     *
     * @param id the id of the entity
     * @return the entity
     */
    @Override
    @Transactional(readOnly = true)
    public Optional<AppUser> findOne(Long id) {
        log.debug("Request to get AppUser : {}", id);
        return appUserRepository.findById(id);
    }

    /**
     * Delete the appUser by id.
     *
     * @param id the id of the entity
     */
    @Override
    public void delete(Long id) {
        log.debug("Request to delete AppUser : {}", id);
        appUserRepository.deleteById(id);
    }

    @Override
    public UserInfoDTO userLogin(String code) throws Exception {
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, String> param = new HashMap<>();
        param.put("appid", "wx242ca7965f35705e");
        param.put("secret", "f126f1b660abaa9b4ae0cb1dfb498d42");
        param.put("js_code", code);
        param.put("grant_type", "authorization_code");

        String wxResult = HttpClientUtil.doGet(url, param);
        System.out.println(wxResult);
        AppUser appUser = new AppUser();
        if (!"".equals(wxResult)){
            WXSessionModel model = JsonUtils.jsonToPojo(wxResult, WXSessionModel.class);
            User user = userRepository.findOneByLogin(model.getOpenid()).orElse(null);
            if (user==null){

               UserDTO userDTO = new UserDTO();
               userDTO.setActivated(true);
               userDTO.setCreatedBy("admin");
               userDTO.setCreatedDate(Instant.now());
               userDTO.setEmail(code+"@qq.com");
               userDTO.setFirstName("");
               userDTO.setId((long) 0);
               userDTO.setImageUrl("");
               userDTO.setLangKey("secret");
               userDTO.setLastModifiedBy("admin");
               userDTO.setLastModifiedDate(Instant.now());
               userDTO.setLastName("");
               userDTO.setLogin(model.getOpenid());
               user = userService.registerUser(userDTO, "123456");
               appUser.setOpenId(model.getOpenid());
               appUser= appUserRepository.save(appUser);

           }
           appUser = appUserRepository.findByOpenId(model.getOpenid());
           //创建token
            UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(model.getOpenid(), "123456");
            Authentication authentication = authenticationManager.authenticate(authenticationToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            String jwt = tokenProvider.createToken(authentication, true);

            //携带用户身份的信息
            UserDTO userDTO =userService.getUserWithAuthorities()
                .map(UserDTO::new)
                .orElseThrow(() -> new InternalServerErrorException("User could not be found"));

            UserInfoDTO userInfoDTO = new UserInfoDTO();
            userInfoDTO.setIdToken(jwt);
            userInfoDTO.setUserDTO(userDTO);
            userInfoDTO.setAppUser(appUser);
            return userInfoDTO;

        }else {
           throw new Exception("未获取到用户的openid");
        }





    }

    @Override
    public AppUser updateAppuserInfo(String open_id, String name, int age, String phone, String we_chat, String address) throws Exception {
        AppUser appUser = appUserRepository.findByOpenId(open_id);
        if (appUser!=null){
            appUser.setName(name);
            appUser.setAge(age);
            appUser.setPhone(phone);
            appUser.setWeChat(we_chat);
            appUser.setAddress(address);
            appUser = appUserRepository.save(appUser);
            return  appUser;

        }else{
            throw  new Exception("未查到openid为:"+open_id+"的用户信息");
        }

    }

    @Override
    public void creatOrupdateSessionid(String open_id, String session_id) throws Exception {
        User user = userRepository.findOneByLogin(open_id).orElse(null);
        if (user==null){
            throw  new Exception("未查到openid为:"+open_id+"的用户信息");
        }
        if ("".equals(globalData.websocketmap.get(open_id)) || globalData.websocketmap.get(open_id) == null) {
            globalData.websocketmap.put(open_id,session_id);
        } else{
            if (!session_id.equals(globalData.websocketmap.get(open_id))){
                globalData.websocketmap.put(open_id,session_id);
            }
        }
        System.out.println("增加/修改后打印map");
        System.out.println(globalData.websocketmap);

    }

    @Override
    public AppUser updateWechatname(String open_id, String wechatname,String headimage) throws Exception {
        AppUser appUser = appUserRepository.findByOpenId(open_id);
        if (appUser!=null){
            appUser.setWechatname(wechatname);
            appUser.setHeadimage(headimage);
            appUser = appUserRepository.save(appUser);
            return  appUser;

        }else{
            throw  new Exception("未查到openid为:"+open_id+"的用户信息");
        }
    }

    @Override
    public AppUser getPersonnalInfo(String open_id) throws Exception {
        User user = userRepository.findOneByLogin(open_id).orElse(null);
        if (user==null){
            throw  new Exception("未查到openid为:"+open_id+"的用户信息");
        }
        AppUser appUser = appUserRepository.findByOpenId(open_id);
        if (appUser!=null){
            return  appUser;

        }else{
            throw  new Exception("未查到openid为:"+open_id+"的用户信息");
        }

    }


}
